﻿using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;


namespace DailyFx.Common
{

	public static class Win32Api_Threading
	{
		// GetCurrentThread() returns only a pseudo handle. No need for a SafeHandle here .
		[DllImport("kernel32.dll")]
		public static extern IntPtr GetCurrentThread ();

		[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
		[HostProtection(SelfAffectingThreading = true)]
		private static extern UIntPtr SetThreadAffinityMask ( IntPtr handle, UIntPtr mask );


		/// <summary>
		///		Sets the logical CPUs that the current thread is allowed to execute on .
		/// </summary>
		private static UIntPtr setThreadAffinityMask ( params int[] ids )
		{
			ulong mask = 0;
			foreach ( int id in ids )
			{
				if (id < 0 || id >= Environment.ProcessorCount)
					throw new ArgumentOutOfRangeException("CPUId", id.ToString());
				mask |= 1UL << id;
			}

			return SetThreadAffinityMask( GetCurrentThread(), (UIntPtr)mask );
		}
	}
}
